Add _gdk_pixmap_set_as_backing which is a way to get GraphicsExposures on pixmaps...
authorAlexander Larsson <alexl@redhat.com>
Tue, 9 Dec 2008 19:10:59 +0000 (20:10 +0100)
committerAlexander Larsson <alex@localhost.localdomain>
Thu, 2 Apr 2009 08:14:08 +0000 (10:14 +0200)
gdk/gdkinternals.h
gdk/gdkpixmap.c
gdk/gdkpixmap.h
gdk/x11/gdkevents-x11.c

index c9d537828dff0b10c149a797373f39b360b31c2c..0acd6170696eb640f70fb103951fd075bd5f5f7d 100644 (file)
@@ -265,6 +265,11 @@ GdkPixmap *_gdk_bitmap_create_from_data  (GdkDrawable    *drawable,
                                           const gchar    *data,
                                           gint            width,
                                           gint            height);
+void       _gdk_pixmap_set_as_backing    (GdkPixmap      *pixmap,
+                                         GdkWindow      *window,
+                                         int             x_offset,
+                                         int             y_offset);
+                                         
 
 void       _gdk_window_impl_new          (GdkWindow      *window,
                                          GdkWindow      *real_parent,
index 4a67feb4dbdd4efbcf00c5ffd073ca8597ba6daf..3b27eda5890fee0bd489d5aa497216deb9e222c9 100644 (file)
@@ -225,6 +225,9 @@ gdk_pixmap_finalize (GObject *object)
 
   g_object_unref (obj->impl);
   obj->impl = NULL;
+
+  if (obj->backing_for)
+    g_object_unref (obj->backing_for);
   
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -277,6 +280,30 @@ gdk_pixmap_create_from_data (GdkDrawable    *drawable,
 }
 
 
+/* Make GraphicsExposures and NoExposures and similar things report
+ * events on this window. Make sure to ref the pixmap for each operation
+ * that will result in a GraphicsExposure, because the core code will unref
+ * if for each such event. This is so that the pixmap live long enought to
+ * get the events on the window.
+ */
+void
+_gdk_pixmap_set_as_backing (GdkPixmap      *pixmap,
+                           GdkWindow      *window,
+                           int             x_offset,
+                           int             y_offset)
+{
+  GdkPixmapObject *private = (GdkPixmapObject *)pixmap;
+
+  if (private->backing_for)
+    g_object_unref (private->backing_for);
+  private->backing_for = window;
+  if (private->backing_for)
+    g_object_ref (private->backing_for);
+  private->backing_x_offset = x_offset;
+  private->backing_y_offset = y_offset;
+  
+}
+
 static GdkGC *
 gdk_pixmap_create_gc (GdkDrawable     *drawable,
                       GdkGCValues     *values,
index e30903891583360547f64ca7bfd900bd3393e49c..863fa1b49971f838dc9f93ce800eb95d73a56069 100644 (file)
@@ -54,6 +54,9 @@ struct _GdkPixmapObject
   GdkDrawable *impl;  /* window-system-specific delegate object */
 
   gint depth;
+  GdkWindow *backing_for;
+  int backing_x_offset;
+  int backing_y_offset;
 };
 
 struct _GdkPixmapObjectClass
index 26e5de456b31b85efeb428b85cf5e5e9eddc96b9..2a8c32c7792a817b774b0eb0f60372b34616e90a 100644 (file)
@@ -902,6 +902,9 @@ gdk_event_translate (GdkDisplay *display,
   GdkToplevelX11 *toplevel = NULL;
   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
   Window xwindow, filter_xwindow;
+  int exposure_x_offset = 0;
+  int exposure_y_offset = 0;
+  GdkWindow *unref_pixmap = NULL;
   
   return_val = FALSE;
 
@@ -929,13 +932,31 @@ gdk_event_translate (GdkDisplay *display,
    * are reported same as structure events
    */
   get_real_window (display, xevent, &xwindow, &filter_xwindow);
-  
+
   window = gdk_window_lookup_for_display (display, xwindow);
+  
   /* We may receive events such as NoExpose/GraphicsExpose
    * and ShmCompletion for pixmaps
    */
   if (window && !GDK_IS_WINDOW (window))
-    window = NULL;
+    {
+      GdkPixmapObject *pixmap = (GdkPixmapObject *)window;
+      if ((xevent->type == GraphicsExpose ||
+          xevent->type == NoExpose) &&
+         GDK_IS_PIXMAP (window) &&
+         pixmap->backing_for != NULL)
+       {
+         /* Unref the pixmap once for each finished set of GraphicsExposes */
+         if (xevent->type == NoExpose ||
+             xevent->xgraphicsexpose.count == 0)
+           unref_pixmap = window;
+         window = g_object_ref (pixmap->backing_for);
+         exposure_x_offset = pixmap->backing_x_offset;
+         exposure_y_offset = pixmap->backing_x_offset;
+       }
+      else
+       window = NULL;
+    }
   window_private = (GdkWindowObject *) window;
 
   /* We always run the filters for the window where the event
@@ -1660,8 +1681,8 @@ gdk_event_translate (GdkDisplay *display,
             break;
           }
         
-       expose_rect.x = xevent->xgraphicsexpose.x;
-       expose_rect.y = xevent->xgraphicsexpose.y;
+       expose_rect.x = xevent->xgraphicsexpose.x + exposure_x_offset;
+       expose_rect.y = xevent->xgraphicsexpose.y + exposure_y_offset;
        expose_rect.width = xevent->xgraphicsexpose.width;
        expose_rect.height = xevent->xgraphicsexpose.height;
            
@@ -2202,6 +2223,9 @@ gdk_event_translate (GdkDisplay *display,
   
   if (window)
     g_object_unref (window);
+
+  if (unref_pixmap)
+    g_object_unref (unref_pixmap);
   
   return return_val;
 }